/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package iteracon;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import iteracon.tuple.Tuple;

/**
 * Iteracon base abstract class, common to all immutable class
 * @author martin
 */
public abstract class IteraconBase<T> implements List<T>{
//list
 @Override
  public int indexOf(Object o) {
    int index = 0;
    for (T t : this)
      if (t.equals(o))
        return index;
      else
        index++;
    return -1;
  }

  @Override
  public int lastIndexOf(Object o) {
    int index = 0,
        lastIndex=-1;
    for (T t : this){
      if (t.equals(o))
        lastIndex=index;
      index++;
    }
    return lastIndex;
  }
    
  @Override
  public boolean addAll(int index, Collection<? extends T> c) {
    throw new UnsupportedOperationException("immutable type");
  }

  @Override
  public T set(int index, T element) {
    throw new UnsupportedOperationException("immutable type");
  }

  @Override
  public void add(int index, T element) {
    throw new UnsupportedOperationException("immutable type");
  }

  @Override
  public T remove(int index) {
    throw new UnsupportedOperationException("immutable type");
  }
//coll
  @Override
  public boolean isEmpty() {
    return size()!=0;
  }

  @Override
  public boolean contains(Object o) {
    for (T t : this)
      if (o.equals(t))
        return true;
    return false;
  }

  @Override
  public boolean containsAll(Collection<?> c) {
    for (Object o : c)
      if (!contains(o))
        return false;
    return true;
  }

  @Override
  public Object[] toArray() {
    Object [] tmp = new Object[size()];
    int index = 0;
    for (T t : this)
      tmp[index++] = t;
    return tmp;
  }

  @Override
  public <T> T[] toArray(T[] a) {
    int index = 0;
    for (Object t : this)
      if(index<a.length)
        a[index++]=(T)t;
    while (index< a.length)
      a[index++] = null;
    return a;
  }

  @Override
  public boolean add(T e) {
    throw new UnsupportedOperationException("immutable type");
  }

  @Override
  public boolean addAll(Collection<? extends T> c) {
    throw new UnsupportedOperationException("immutable type");
  }
  
  @Override
  public boolean remove(Object o) {
    throw new UnsupportedOperationException("immutable type");
  }


  @Override
  public boolean removeAll(Collection<?> c) {
    throw new UnsupportedOperationException("immutable type");
  }

  @Override
  public boolean retainAll(Collection<?> c) {
    throw new UnsupportedOperationException("immutable type");
  }

  @Override
  public void clear() {
    throw new UnsupportedOperationException("immutable type");
  }
//object
  @Override
  public boolean equals(Object o){
    if(o instanceof List){
      Iterator a = iterator(),
               b = ((Tuple)o).iterator();
      while(a.hasNext() && b.hasNext()){
        if (!a.next().equals(b.next()))
          return false;
      }
      if (a.hasNext() || b.hasNext())
        return false;
      return true;
    }
    return false;
  }
  
  @Override
  public int hashCode(){
    int hash = 1;
    for (Object o : this)
      hash = hash*13 + o.hashCode();
    return hash;
  }
  
  @Override
  public String toString(){
    String str = "(";
    for (Object o : this)
      str = str + o.toString() + ", ";
    return str.substring(0, str.length()-2) + ")";
  }
}
